<?php

namespace App\Admin\Controllers\Aliyun;

use AlibabaCloud\Client\Exception\ClientException;
use App\Admin\Actions\Aliyun\SetupDnsRemark;
use App\Admin\Actions\GoBackButton;
use App\Enums\DnsLine;
use App\Enums\DnsTtl;
use App\Enums\DnsType;
use App\Models\Aliyun;
use App\Models\Dns;
use Dcat\Admin\Exception\InvalidArgumentException;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Layout\Content;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Controller;
use Symfony\Component\HttpFoundation\Response;

class DnsController extends Controller
{
    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     */
    public function index(Content $content, Aliyun $aliyun, string $domain): Content
    {
        return $content->header('解析记录')
            ->description($domain)
            ->body($this->grid($aliyun, $domain));
    }

    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     */
    public function grid(Aliyun $aliyun, $domain): Grid
    {
        return Grid::make(Dns::initAliyun($aliyun), function (Grid $grid) use ($aliyun, $domain) {
            $grid->disableBatchDelete(false);

            $grid->tools([
                new GoBackButton,
            ]);

            $grid->actions([new SetupDnsRemark($aliyun)]);

            $grid->column('RR', '主机记录')
                ->copyable();
            $grid->column('Type', '记录类型')
                ->using(DnsType::TYPE_MAP);
            $grid->column('Line', '解析线路')
                ->using(DnsLine::LINE_MAP);
            $grid->column('Status', '状态');
            $grid->column('Value', '记录值')
                ->copyable();
            $grid->column('Remark', '备注');
        });
    }

    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     */
    public function create(Content $content, Aliyun $aliyun, string $domain): Content
    {
        return $content
            ->header('新增记录')
            ->description($domain)
            ->body($this->form($aliyun, $domain));
    }

    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     */
    public function form(Aliyun $aliyun, string $domain): Form
    {
        return Form::make(Dns::initAliyun($aliyun), function (Form $form) use ($domain) {
            $form->hidden('DomainName')
                ->value($domain);
            $form->text('RR', '主机记录')
                ->required();
            $form->select('Type', '记录类型')
                ->options(DnsType::SELECT_TYPE_MAP)
                ->default('A')
                ->required();
            $form->select('Line', '解析线路')
                ->options(DnsLine::LINE_MAP)
                ->default('default')
                ->required();
            $form->text('Value', '记录值')
                ->required();
            $form->select('TTL', 'TTL')
                ->options(DnsTtl::TTL_MAP)
                ->default(600)
                ->required();
        });
    }

    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     * @throws Exception
     */
    public function store(Aliyun $aliyun, string $domain): JsonResponse
    {
        return $this->form($aliyun, $domain)->store();
    }

    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     */
    public function edit(Content $content, Aliyun $aliyun, string $domain, string $id): Content
    {
        return $content
            ->header('修改记录')
            ->description($domain)
            ->body($this->form($aliyun, $domain)->edit($id));
    }

    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     * @throws Exception
     */
    public function update(Aliyun $aliyun, string $domain, string $id): Response
    {
        return $this->form($aliyun, $domain)->update($id);
    }

    /**
     * @throws ClientException
     * @throws InvalidArgumentException
     * @throws Exception
     */
    public function destroy(Aliyun $aliyun, $domain, $id)
    {
        return $this->form($aliyun, $domain)->destroy($id);
    }
}
